package com.ponhu.ea2.stockcenter.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.google.common.collect.Lists;
import com.ponhu.ea2.common.basic.model.PagedResult;
import com.ponhu.ea2.common.basic.model.ResponseBean;
import com.ponhu.ea2.stockcenter.config.JuWoImportDataListenter;
import com.ponhu.ea2.stockcenter.dto.StockDiffQueryDto;
import com.ponhu.ea2.stockcenter.enums.DefinedSystem;
import com.ponhu.ea2.stockcenter.service.bms.StockCheckService;
import com.ponhu.ea2.stockcenter.service.bms.StockCommonService;
import com.ponhu.ea2.stockcenter.service.bms.StockForOMSService;
import com.ponhu.ea2.stockcenter.service.bms.StockForPurchaseCenterService;
import com.ponhu.ea2.stockcenter.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Method;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/stockCheck")
@Api(tags = "库存校验接口", value = "StockCheckController")
public class StockCheckController {

    @DubboReference(version = "1.0.0", check = false, methods = {
            @Method(name = "correctStockByInventoryCodes", timeout = 600000)
    })
    private StockCheckService stockCheckService;

    @DubboReference(version = "1.0.0", check = false)
    private StockCommonService stockCommonService;

    @DubboReference(version = "1.0.0", check = false, methods = {
            @Method(name = "cancelSalesOrderOccupyStock", timeout = 600000)
    })
    private StockForOMSService stockForOMSService;

    @DubboReference(version = "1.0.0", check = false, methods = {
            @Method(name = "cancelPurchaseReturnApplyOccupyStock", timeout = 600000)
    })
    private StockForPurchaseCenterService stockForPurchaseCenterService;

    @Autowired
    private JuWoImportDataListenter juWoImportDataListenter;

    /**
     * 查询库存对比差异文件下载列表
     * @param stockDiffQueryDto
     * @return
     */
    @ApiOperation(value = "查询库存对比差异文件下载列表")
    @PostMapping("/getAllStockDiffUploadLogs")
    public ResponseBean<PagedResult<StockDiffUploadLogsVo>> getAllStockDiffUploadLogs(
            @RequestBody StockDiffQueryDto stockDiffQueryDto) {

        return ResponseBean.ok(stockCheckService.getAllStockDiffUploadLogs(stockDiffQueryDto));
    }

    /**
     * 上传巨沃数据&导出库存中心和巨沃差异对比统计
     *
     * @param uploadFile
     * @param response
     */
    @ApiOperation(value = "上传巨沃数据&导出库存中心和巨沃差异对比统计")
    @PostMapping("/exportDiffVo1")
    public void exportDiffVo1(@RequestBody MultipartFile uploadFile, HttpServletResponse response) {
        BufferedReader br = null;
        OutputStream output = null;
        try {

            long start = System.currentTimeMillis();
            EasyExcel.read(uploadFile.getInputStream(), JuWoImportData.class, juWoImportDataListenter).sheet(0).doRead();
            System.out.printf("\033[32m EasyExcel.read ===>> %s ms \033[0m\n", System.currentTimeMillis() - start);

            output = response.getOutputStream();
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msexcel");
            String fileName = URLEncoder.encode("库存中心和巨沃差异对比统计", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            stockCheckService.initTemStockDifferenceService();

            ExcelWriter excelWriter = EasyExcelFactory.write(output, TemStockDifferenceVo.class).build();
            WriteSheet sheet1 = EasyExcelFactory.writerSheet(1, "巨沃和库存中心都存在").build();
            WriteSheet sheet2 = EasyExcelFactory.writerSheet(2, "库存中心存在&巨沃不存在").build();
            WriteSheet sheet3 = EasyExcelFactory.writerSheet(3, "巨沃存在&库存中心不存在").build();
            WriteSheet sheet4 = EasyExcelFactory.writerSheet(4, "巨沃存在&商品系统不存在").build();
//            excelWriter.write(stockCheckService.exportStockDifferenceVos("存在", "存在"), sheet1);
//            excelWriter.write(stockCheckService.exportStockDifferenceVos("存在", "不存在"), sheet2);
//            excelWriter.write(stockCheckService.exportStockDifferenceVos("不存在", "存在"), sheet3);
//            excelWriter.write(stockCheckService.exportStockDifferenceVos("商品系统不存在", "存在"), sheet4);
            excelWriter.finish();
            response.flushBuffer();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 导出库存中心和巨沃差异对比统计
     *
     * @param response
     */
    @ApiOperation(value = "导出库存中心和巨沃差异对比统计")
    @PostMapping("/exportDiffVo/{type}")
    public void exportDiffVo(@PathVariable("type") int type, HttpServletResponse response) {
        BufferedReader br = null;
        OutputStream output = null;
        try {
            output = response.getOutputStream();
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msexcel");
            String fileName = URLEncoder.encode("库存中心和巨沃差异对比统计", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            ExcelWriter excelWriter = EasyExcelFactory.write(output, TemStockDifferenceVo.class).build();
            WriteSheet sheet1 = EasyExcelFactory.writerSheet(1, "巨沃和库存中心都存在").build();
            WriteSheet sheet2 = EasyExcelFactory.writerSheet(2, "库存中心存在&巨沃不存在").build();
            WriteSheet sheet3 = EasyExcelFactory.writerSheet(3, "巨沃存在&库存中心不存在").build();
            WriteSheet sheet4 = EasyExcelFactory.writerSheet(4, "巨沃存在&商品系统不存在").build();

            long start = System.currentTimeMillis();
            List<TemStockDifferenceVo> temStockDifferenceVos = stockCheckService.exportStockDifferenceVos(type).getData();
            log.info("导出库存中心和巨沃差异对比统计 ===>> stockCheckService.exportStockDifferenceVos() " +
                    "===>> 对比耗时：{} ", System.currentTimeMillis() - start);

            if (CollectionUtils.isEmpty(temStockDifferenceVos)) return;

            excelWriter.write(temStockDifferenceVos.parallelStream().filter(differenceVo -> differenceVo.getWhHas().equals("存在")
                    && differenceVo.getJwHas().equals("存在")).collect(Collectors.toList()), sheet1);
            excelWriter.write(temStockDifferenceVos.parallelStream().filter(differenceVo -> differenceVo.getWhHas().equals("存在")
                    && differenceVo.getJwHas().equals("不存在")).collect(Collectors.toList()), sheet2);
            excelWriter.write(temStockDifferenceVos.parallelStream().filter(differenceVo -> differenceVo.getJwHas().equals("存在")
                    && differenceVo.getWhHas().equals("不存在")).collect(Collectors.toList()), sheet3);
            excelWriter.write(temStockDifferenceVos.parallelStream().filter(differenceVo -> differenceVo.getJwHas().equals("存在")
                    && differenceVo.getWhHas().equals("商品系统不存在")).collect(Collectors.toList()), sheet4);
            excelWriter.finish();
            response.flushBuffer();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 上传货品编码修复相关货品库存数据
     *
     * @param uploadFile
     * @param response
     */
    @ApiOperation(value = "上传货品编码修复相关货品库存数据")
    @PostMapping("/correctStockByInventoryCodes")
    public String correctStockByInventoryCodes(@RequestBody MultipartFile uploadFile, HttpServletResponse response) {
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
            Reader reader = new InputStreamReader(uploadFile.getInputStream());
            bufferedReader = new BufferedReader(reader);
            List<String> inventoryCodeList = Lists.newArrayList();
            String inventoryCode;
            while ((inventoryCode = bufferedReader.readLine()) != null) {
                if (StringUtils.isNotEmpty(inventoryCode))
                    inventoryCodeList.add(inventoryCode.trim());
            }

            if (CollectionUtils.isEmpty(inventoryCodeList)) return "上传的货品编码列表不可为空";

            inventoryCodeList = stockCheckService.correctStockByInventoryCodes(inventoryCodeList, 2).getData();
            if (CollectionUtils.isEmpty(inventoryCodeList)) inventoryCodeList = Lists.newArrayList();

            response.setCharacterEncoding("utf-8");
            response.setContentType("application/octet-stream");
            String fileName = URLEncoder.encode("修复货品库存数据失败货品编码列表", "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".txt");

            Writer writer = new OutputStreamWriter(response.getOutputStream());
            bufferedWriter = new BufferedWriter(writer);
            Iterator<String> iterator = inventoryCodeList.iterator();
            while (iterator.hasNext()) {
                bufferedWriter.write(iterator.next());
                bufferedWriter.newLine();
            }

            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedWriter != null) {
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 上传订单编号批量取消订单并释放销售库存占用/采退单占用
     *
     * @param uploadFile
     * @param response
     */
    @ApiOperation(value = "上传订单编号批量取消订单并释放销售库存占用/采退单占用")
    @PostMapping("/batchCancelStockOccupy")
    public String batchCancelStockOccupy(@RequestBody MultipartFile uploadFile, HttpServletResponse response) {
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
            Reader reader = new InputStreamReader(uploadFile.getInputStream());
            bufferedReader = new BufferedReader(reader);
            List<String> orderNoList = Lists.newArrayList();
            String orderNo;
            while ((orderNo = bufferedReader.readLine()) != null) {
                if (StringUtils.isNotEmpty(orderNo))
                    orderNoList.add(orderNo.trim());
            }

            if (CollectionUtils.isEmpty(orderNoList)) return "上传的订单列表不可为空";

            List<String> omsList = orderNoList.stream().map(orderSn -> {

                String stockRequestToken = stockCommonService
                        .getStockRequestToken(DefinedSystem.OMS).getData();

                ReturnResponseBean<OrderOccupyInfoVO> result = stockForOMSService
                        .cancelSalesOrderOccupyStock(stockRequestToken, orderSn);

                if (result.getCode() != 200) return orderSn;
                else return null;
            }).filter(StringUtils::isNotEmpty).collect(Collectors.toList());

            List<String> purchaseList = orderNoList.stream().map(orderSn -> {

                String stockRequestToken = stockCommonService
                        .getStockRequestToken(DefinedSystem.PURCHASE_CENTER).getData();

                ReturnResponseBean result = stockForPurchaseCenterService
                        .cancelPurchaseReturnApplyOccupyStock(stockRequestToken, orderSn);

                if (result.getCode() != 200) return orderSn;
                else return null;
            }).filter(StringUtils::isNotEmpty).collect(Collectors.toList());

            List<String> result = new ArrayList<>();
            result.addAll(omsList);
            result.addAll(purchaseList);

            response.setCharacterEncoding("utf-8");
            response.setContentType("application/octet-stream");
            String fileName = URLEncoder.encode("批量取消订单失败订单编号列表", "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".txt");

            Writer writer = new OutputStreamWriter(response.getOutputStream());
            bufferedWriter = new BufferedWriter(writer);
            Iterator<String> iterator = result.iterator();
            while (iterator.hasNext()) {
                bufferedWriter.write(iterator.next());
                bufferedWriter.newLine();
            }

            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedWriter != null) {
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
